package com.zenithmind.library.pojo.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zenithmind.common.base.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;

/**
 * 罚金记录实体
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "罚金记录实体", description = "图书罚金记录信息")
@TableName("lib_fine_record")
public class FineRecord extends BaseEntity {

    @NotBlank(message = "用户ID不能为空")
    @Schema(description = "用户ID")
    private String userId;

    @NotBlank(message = "借阅记录ID不能为空")
    @Schema(description = "借阅记录ID")
    private String borrowRecordId;

    @NotNull(message = "罚金类型不能为空")
    @Schema(description = "罚金类型 (1-逾期罚金, 2-损坏赔偿, 3-丢失赔偿)")
    private Integer fineType;

    @NotNull(message = "罚金金额不能为空")
    @Schema(description = "罚金金额")
    private BigDecimal fineAmount;

    @Schema(description = "已支付金额")
    private BigDecimal paidAmount;

    @Schema(description = "支付状态 (0-未支付, 1-已支付, 2-部分支付)")
    private Integer paymentStatus;

    @Size(max = 50, message = "支付方式长度不能超过50个字符")
    @Schema(description = "支付方式")
    private String paymentMethod;

    @Schema(description = "支付时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime paymentTime;

    @Size(max = 100, message = "支付凭证号长度不能超过100个字符")
    @Schema(description = "支付凭证号")
    private String paymentReference;

    @Size(max = 500, message = "罚金说明长度不能超过500个字符")
    @Schema(description = "罚金说明")
    private String description;

    @Schema(description = "操作员ID")
    private String operatorId;

    /**
     * 获取罚金类型名称
     */
    public String getFineTypeName() {
        if (fineType == null) {
            return "未知";
        }
        return switch (fineType) {
            case 1 -> "逾期罚金";
            case 2 -> "损坏赔偿";
            case 3 -> "丢失赔偿";
            default -> "未知";
        };
    }

    /**
     * 获取支付状态名称
     */
    public String getPaymentStatusName() {
        if (paymentStatus == null) {
            return "未知";
        }
        return switch (paymentStatus) {
            case 0 -> "未支付";
            case 1 -> "已支付";
            case 2 -> "部分支付";
            default -> "未知";
        };
    }

    /**
     * 计算未支付金额
     */
    public BigDecimal getUnpaidAmount() {
        if (fineAmount == null) {
            return BigDecimal.ZERO;
        }
        if (paidAmount == null) {
            return fineAmount;
        }
        return fineAmount.subtract(paidAmount);
    }

    /**
     * 判断是否已完全支付
     */
    public boolean isFullyPaid() {
        return paymentStatus != null && paymentStatus == 1;
    }

    /**
     * 判断是否未支付
     */
    public boolean isUnpaid() {
        return paymentStatus == null || paymentStatus == 0;
    }

    /**
     * 判断是否部分支付
     */
    public boolean isPartiallyPaid() {
        return paymentStatus != null && paymentStatus == 2;
    }

    /**
     * 判断是否需要支付
     */
    public boolean needsPayment() {
        return !isFullyPaid() && getUnpaidAmount().compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * 计算支付进度（百分比）
     */
    public BigDecimal getPaymentProgress() {
        if (fineAmount == null || fineAmount.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.valueOf(100);
        }
        if (paidAmount == null) {
            return BigDecimal.ZERO;
        }
        return paidAmount.divide(fineAmount, 4, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
    }

    /**
     * 记录支付
     */
    public boolean recordPayment(BigDecimal amount, String method, String reference) {
        if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
            return false;
        }

        paidAmount = (paidAmount == null ? BigDecimal.ZERO : paidAmount).add(amount);
        paymentMethod = method;
        paymentReference = reference;
        paymentTime = LocalDateTime.now();

        // 更新支付状态
        if (paidAmount.compareTo(fineAmount) >= 0) {
            paymentStatus = 1; // 已支付
            paidAmount = fineAmount; // 确保不超过应付金额
        } else {
            paymentStatus = 2; // 部分支付
        }

        return true;
    }

    /**
     * 获取罚金严重程度
     */
    public String getSeverityLevel() {
        if (fineAmount == null) {
            return "未知";
        }

        if (fineAmount.compareTo(BigDecimal.valueOf(10)) <= 0) {
            return "轻微";
        } else if (fineAmount.compareTo(BigDecimal.valueOf(50)) <= 0) {
            return "一般";
        } else if (fineAmount.compareTo(BigDecimal.valueOf(100)) <= 0) {
            return "严重";
        } else {
            return "非常严重";
        }
    }
}
